package com.yunhe.estatemanage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yunhe.common.constant.MessageConsts;
import com.yunhe.common.constant.PortalConstant;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.filter.ServerContextHolder;
import com.yunhe.common.model.ResultObject;
import com.yunhe.common.model.authority.MessageCenter;
import com.yunhe.common.model.authority.RealStation;
import com.yunhe.common.model.authority.User;
import com.yunhe.common.model.authority.UserProjectOrg;
import com.yunhe.common.model.company.Company;
import com.yunhe.common.model.mybatis.PageResult;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.RedisClient;
import com.yunhe.common.util.StringUtil;
import com.yunhe.estatemanage.client.AuthorityClient;
import com.yunhe.estatemanage.constant.EstateManageConstant;
import com.yunhe.estatemanage.domain.IncidentSatisfactionTable;
import com.yunhe.estatemanage.domain.ProcessStatus;
import com.yunhe.estatemanage.domain.ReportRepair;
import com.yunhe.estatemanage.model.ReportRepairCondition;
import com.yunhe.estatemanage.model.ReportRepairHandle;
import com.yunhe.estatemanage.model.ReportRepairStatistics;
import com.yunhe.estatemanage.model.ReportRepairView;
import com.yunhe.estatemanage.repository.IncidentSatisfactionTableRepository;
import com.yunhe.estatemanage.repository.ProcessStatusRepository;
import com.yunhe.estatemanage.repository.ReportRepairRepository;
import com.yunhe.estatemanage.service.ReportRepairService;
import com.yunhe.estatemanage.util.MyHeaderUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.yunhe.common.util.CollectionUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: ReportRepairServiceImpl
 * @Description:
 * @author: GongDaCheng
 * @Date: 16:22 2021/9/3
 */
@Service
@Slf4j
public class ReportRepairServiceImpl implements ReportRepairService {

    @Autowired
    private ReportRepairRepository reportRepairRepository;

    @Autowired
    private ProcessStatusRepository processStatusRepository;

    @Autowired
    private IncidentSatisfactionTableRepository incidentSatisfactionTableRepository;

    @Autowired
    private MyHeaderUtil myHeaderUtil;

    @Autowired
    private AuthorityClient authorityClient;

    @Autowired
    private RedisClient redisClient;

    private static LinkedBlockingQueue<MessageCenter> dataListBOQueue = new LinkedBlockingQueue<>();

    @Override
    public int create(ReportRepair reportRepair) throws ArgumentErrorException {
        reportRepair.setCurrentStatus(EstateManageConstant.Current_Status_Type.To_Be_Distributed.value());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        reportRepair.setSubmissionTime(sdf.format(new Date()));
        int count = reportRepairRepository.create(reportRepair);
        ProcessStatus createProcess = new ProcessStatus();
        createProcess.setReportForRepairId(reportRepair.getId());
        createProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Submit_Demand.value());
        createProcess.setCurrentStatus(EstateManageConstant.Current_Status_Type.To_Be_Distributed.value());
        createProcess.setCreateTime(sdf.format(new Date()));
        createProcess.setUpdateTime(sdf.format(new Date()));
        processStatusRepository.create(createProcess);
        return count;
    }

    private void pushMessageToApp(String userIds, String projectCode, ReportRepair reportRepair) {
        //消息推送（App只面向园区推送）
        Map<String, String> extras = new HashMap<>();
        extras.put("stationId", projectCode);
        String content = reportRepair.getProblemDescription().length() > 15 ? reportRepair.getProblemDescription().substring(0, 14) + "......" : reportRepair.getProblemDescription();
        authorityClient.pushMessageByUserIds(userIds, "报事报修", content, extras);
    }

    private void sendMessageCenter(ReportRepair reportRepair, Long headerUser, String flag, Long distributeOrgId, Long distributePersonId) throws InterruptedException{
        long startTime = System.currentTimeMillis();
        //创建线程池 批量处理数据
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(() -> {
            batchDataProcessing();
        });
        if(distributePersonId != null){
            MessageCenter messageCenter = new MessageCenter();
            messageCenter.setBusinessId(reportRepair.getId());
            messageCenter.setMessageTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date()));
            messageCenter.setMessageType(MessageConsts.MessageType.ReportForRepair.value());
            messageCenter.setContent(JSON.toJSONString(reportRepair));
            messageCenter.setMessageSendPerson(headerUser);
            messageCenter.setPersonType(MessageConsts.PersonType.StationUser.value());
            if ("app".equals(flag)) {
                messageCenter.setMessagePerson(distributePersonId);
                messageCenter.setMessageDestination(MessageConsts.MessageDestination.parkApp.value());
                messageCenter.setPersonType(MessageConsts.PersonType.StationUser.value());
            } else if ("weChat".equals(flag)){
                messageCenter.setMessagePerson(reportRepair.getContactPersonId());
                messageCenter.setMessageDestination(MessageConsts.MessageDestination.parkWeChat.value());
                messageCenter.setPersonType(MessageConsts.PersonType.CompanyUser.value());
                messageCenter.setCompanyId(reportRepair.getCompanyId());
            }
            dataListBOQueue.add(messageCenter);
        }else {
            //查询当前部门下的人
            ResponseEntity<ResultObject<List<UserProjectOrg>>> responseEntity =
                    authorityClient.getUserByOrgIdAndStationId(distributeOrgId, Long.valueOf(ServerContextHolder.getContext().getProjectCode()));
            if (responseEntity.getStatusCode().is2xxSuccessful()){
                Object results = responseEntity.getBody().getResults();
                List<UserProjectOrg> users = JSON.parseArray(JSON.toJSONString(results), UserProjectOrg.class);
                if (!CollectionUtils.isEmpty(users)){
                    for (UserProjectOrg user : users) {
                        MessageCenter messageCenter = new MessageCenter();
                        messageCenter.setBusinessId(reportRepair.getId());
                        messageCenter.setMessageTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date()));
                        messageCenter.setMessageType(MessageConsts.MessageType.ReportForRepair.value());
                        messageCenter.setMessagePerson(user.getUserId());
                        messageCenter.setContent(JSON.toJSONString(reportRepair));
                        messageCenter.setMessageSendPerson(headerUser);
                        messageCenter.setPersonType(MessageConsts.PersonType.StationUser.value());
                        messageCenter.setMessageDestination(MessageConsts.MessageDestination.parkApp.value());
                        messageCenter.setPersonType(MessageConsts.PersonType.StationUser.value());
                        dataListBOQueue.add(messageCenter);
                    }
                }
            }
        }

        ResponseEntity<ResultObject<List<User>>> responseEntity = authorityClient.findStationUserByStationId(Long.valueOf(reportRepair.getStationId()));
        if (responseEntity != null){
            if (responseEntity.getStatusCode().is2xxSuccessful()){
                Object results = responseEntity.getBody().getResults();
                List<User> users = JSON.parseArray(JSON.toJSONString(results), User.class);
                if (!CollectionUtils.isEmpty(users)){
                    for (User user : users) {

                    }
                }
            }
        }

        dataListBOQueue.add(new MessageCenter());
        long endTime = System.currentTimeMillis();
        log.info("数据处理所需时间：{}",(endTime-startTime));
        log.info("数据处理结束");
        executorService.shutdown();
        executorService.awaitTermination(20, TimeUnit.SECONDS);
    }

    private void batchDataProcessing(){
        try{
            for (; ; ){
                List<MessageCenter> dataLists = new ArrayList<>(100);
                for (int i = 0; i < 50; i++){
                    MessageCenter take = dataListBOQueue.take();
                    if (take == null || take.getBusinessId() ==null) {
                        if (!CollectionUtils.isEmpty(dataLists)) {
                            authorityClient.batchCreateMessageCenter(dataLists);
                        }
                        return;
                    } else {
                        dataLists.add(take);
                    }
                }
                if (!CollectionUtils.isEmpty(dataLists)) {
                    authorityClient.batchCreateMessageCenter(dataLists);
                    dataLists.clear();
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int delete(Long id) {
        return reportRepairRepository.deleteByPrimaryKey(id);
    }

    @Override
    public int update(ReportRepair reportRepair) {
        return reportRepairRepository.updateByPrimaryKey(reportRepair);
    }

    @Override
    public ReportRepair findById(Long id) {
        ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(id);
        List<ProcessStatus> feedbackHistory = processStatusRepository.getFeedbackHistory(reportRepair.getId());
        reportRepair.setFeedbackHistory(feedbackHistory);
        return reportRepair;
    }

    @Override
    public PageResult findReportRepairByConditionWeb(ReportRepairCondition reportRepairCondition) {
        PageResult result = null;
        if (CollectionUtil.isEmpty(reportRepairCondition.getStationIds())) {
            List<Long> stationIds = new ArrayList<>();
            String projectCode = ServerContextHolder.getContext().getProjectCode();
            if (!StringUtil.isEmpty(projectCode)) {
                ResponseEntity<ResultObject> responseEntity = authorityClient.searchStationAndOfficeByStationId(Long.valueOf(projectCode));
                if (responseEntity != null) {
                    if (responseEntity.getStatusCode().is2xxSuccessful()) {
                        Object results = responseEntity.getBody().getResults();
                        List<RealStation> realStations = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                        for (RealStation realStation : realStations) {
                            stationIds.add(realStation.getId());
                        }
                    }
                }
                reportRepairCondition.setStationIds(stationIds);
            }
        }

        PageHelper.startPage(reportRepairCondition.getPage(), reportRepairCondition.getSize());
        List<ReportRepair> reportRepairs = reportRepairRepository.findReportRepairByConditionWeb(reportRepairCondition);
        PageInfo<ReportRepair> pageInfo = new PageInfo<>(reportRepairs);
        result = new PageResult(reportRepairCondition.getPage(), reportRepairCondition.getSize(), (int)pageInfo.getTotal(), reportRepairs);
        return result;
    }

    @Override
    public List<ReportRepair> findReportRepairByConditionMob(ReportRepairCondition reportRepairCondition) throws ArgumentErrorException {
        if (CollectionUtil.isEmpty(reportRepairCondition.getStationIds())) {
            List<Long> stationIds = new ArrayList<>();
            if (reportRepairCondition.getVirtualStationId() != null) {
                ResponseEntity<ResultObject> responseEntity = authorityClient.searchStationAndOfficeByStationId(reportRepairCondition.getVirtualStationId());
                if (responseEntity != null) {
                    if (responseEntity.getStatusCode().is2xxSuccessful()) {
                        Object results = responseEntity.getBody().getResults();
                        List<RealStation> realStations = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                        for (RealStation realStation : realStations) {
                            stationIds.add(realStation.getId());
                        }
                    }
                }
                reportRepairCondition.setStationIds(stationIds);
            }
        }
        //获取app 当前人的组织信息
        List<Long> dealWithOrgIds = new ArrayList<>();
        if(reportRepairCondition.getCurrentOperatorId() != null){
            //查询当前人的归属组织以及协调组织
            String orgIdStr = redisClient.get("Org:" + reportRepairCondition.getCurrentOperatorId());
            if(!StringUtil.isEmpty(orgIdStr)){
                String[] split = orgIdStr.split("-");
                String s = split[0];
                dealWithOrgIds.add(Long.valueOf(s));
            }else {
                throw new ArgumentErrorException("该账号没有相关组织！");
            }
            String synergyOrgIdStr = redisClient.get("SynergyOrg:" + reportRepairCondition.getCurrentOperatorId());
            if(!StringUtil.isEmpty(synergyOrgIdStr)){
                String[] split = synergyOrgIdStr.split("-");
                String s = split[0];
                String[] split1 = s.split(",");
                if(split1.length>0){
                    for (String s1 : split1) {
                        dealWithOrgIds.add(Long.valueOf(s1));
                    }
                }
            }
            reportRepairCondition.setDealWithOrgIds(dealWithOrgIds);
        }
        List<ReportRepair> reportRepairs = reportRepairRepository.findReportRepairByConditionMob(reportRepairCondition);
        for (ReportRepair reportRepair : reportRepairs) {
            //根据报事报修id查询对应的状态流程，获取状态节点
            List<ProcessStatus> processByReportRepairId = processStatusRepository.getProcessByReportRepairId(reportRepair.getId());
            if (!CollectionUtil.isEmpty(processByReportRepairId)){
                int length = processByReportRepairId.size();
                //因为查询出的流程根据创建日期升序排序，所以最新的状态流程在list最后一个，所以取length-1
                reportRepair.setProcessNode(processByReportRepairId.get(length - 1).getProcessNode());
            }
            List<ProcessStatus> feedbackHistory = processStatusRepository.getFeedbackHistory(reportRepair.getId());
            reportRepair.setFeedbackHistory(feedbackHistory);
        }

        return reportRepairs;
    }

    @Override
    public PageResult findReportRepairByConditionMobPaging(ReportRepairCondition reportRepairCondition) throws ArgumentErrorException {
        PageResult result = null;
        if (CollectionUtil.isEmpty(reportRepairCondition.getStationIds())) {
            List<Long> stationIds = new ArrayList<>();
            if (reportRepairCondition.getVirtualStationId() != null) {
                ResponseEntity<ResultObject> responseEntity = authorityClient.searchStationAndOfficeByStationId(reportRepairCondition.getVirtualStationId());
                if (responseEntity != null) {
                    if (responseEntity.getStatusCode().is2xxSuccessful()) {
                        Object results = responseEntity.getBody().getResults();
                        List<RealStation> realStations = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                        for (RealStation realStation : realStations) {
                            stationIds.add(realStation.getId());
                        }
                    }
                }
                reportRepairCondition.setStationIds(stationIds);
            }
        }
        //获取app 当前人的组织信息
        List<Long> dealWithOrgIds = new ArrayList<>();
        if(reportRepairCondition.getCurrentOperatorId() != null){
            //查询当前人的归属组织以及协调组织
            String orgIdStr = redisClient.get("Org:" + reportRepairCondition.getCurrentOperatorId());
            if(!StringUtil.isEmpty(orgIdStr)){
                String[] split = orgIdStr.split("-");
                String s = split[0];
                dealWithOrgIds.add(Long.valueOf(s));
            }else {
                throw new ArgumentErrorException("该账号没有相关组织！");
            }
            String synergyOrgIdStr = redisClient.get("SynergyOrg:" + reportRepairCondition.getCurrentOperatorId());
            if(!StringUtil.isEmpty(synergyOrgIdStr)){
                String[] split = synergyOrgIdStr.split("-");
                String s = split[0];
                String[] split1 = s.split(",");
                if(split1.length>0){
                    for (String s1 : split1) {
                        dealWithOrgIds.add(Long.valueOf(s1));
                    }
                }
            }
            reportRepairCondition.setDealWithOrgIds(dealWithOrgIds);
        }

        PageHelper.startPage(reportRepairCondition.getPage(), reportRepairCondition.getSize());
        List<ReportRepair> reportRepairs = reportRepairRepository.findReportRepairByConditionMob(reportRepairCondition);
        for (ReportRepair reportRepair : reportRepairs) {
            //根据报事报修id查询对应的状态流程，获取状态节点
            List<ProcessStatus> processByReportRepairId = processStatusRepository.getProcessByReportRepairId(reportRepair.getId());
            if (!CollectionUtil.isEmpty(processByReportRepairId)){
                int length = processByReportRepairId.size();
                //因为查询出的流程根据创建日期升序排序，所以最新的状态流程在list最后一个，所以取length-1
                reportRepair.setProcessNode(processByReportRepairId.get(length - 1).getProcessNode());
            }
            List<ProcessStatus> feedbackHistory = processStatusRepository.getFeedbackHistory(reportRepair.getId());
            reportRepair.setFeedbackHistory(feedbackHistory);
        }
        PageInfo<ReportRepair> pageInfo = new PageInfo<>(reportRepairs);
        result = new PageResult(reportRepairCondition.getPage(), reportRepairCondition.getSize(), (int)pageInfo.getTotal(), reportRepairs);
        return result;
    }

    @Override
    public ReportRepairStatistics reportRepairStatistics(List<Long> stationIds) {
        ReportRepairStatistics reportRepairStatistics = new ReportRepairStatistics();
        //如果传入园区id为空，则获取的数据为当前园区下的所有真实园区的数据
        List<Long> stationIdList = new ArrayList<>();
        if (CollectionUtil.isEmpty(stationIds)) {
            String projectCode = ServerContextHolder.getContext().getProjectCode();
            if (!StringUtil.isEmpty(projectCode)) {
                ResponseEntity<ResultObject> responseEntity = authorityClient.searchStationAndOfficeByStationId(Long.valueOf(projectCode));
                if (responseEntity != null) {
                    if (responseEntity.getStatusCode().is2xxSuccessful()) {
                        Object results = responseEntity.getBody().getResults();
                        List<RealStation> realStations = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                        for (RealStation realStation : realStations) {
                            stationIdList.add(realStation.getId());
                        }
                    }
                }
            }
        }else {
            stationIdList.addAll(stationIds);
        }
        //待办事项
        ReportRepairCondition todoCondition = new ReportRepairCondition();
        todoCondition.setCurrentStatus(EstateManageConstant.Current_Status_Type.To_Be_Distributed.value());
        todoCondition.setStationIds(stationIdList);
        List<ReportRepair> todoReportRepairs = reportRepairRepository.findReportRepairByConditionWeb(todoCondition);
        reportRepairStatistics.setTodoCount(todoReportRepairs.size());
        //处理中事项
        ReportRepairCondition processingCondition = new ReportRepairCondition();
        processingCondition.setCurrentStatus(EstateManageConstant.Current_Status_Type.Processing.value());
        processingCondition.setStationIds(stationIdList);
        List<ReportRepair> processingReportRepairs = reportRepairRepository.findReportRepairByConditionWeb(processingCondition);
        reportRepairStatistics.setProcessingCount(processingReportRepairs.size());
        //完结事项
        ReportRepairCondition completeCondition = new ReportRepairCondition();
        completeCondition.setCurrentStatus(EstateManageConstant.Current_Status_Type.Finished.value());
        completeCondition.setStationIds(stationIdList);
        List<ReportRepair> completeReportRepairs = reportRepairRepository.findReportRepairByConditionWeb(completeCondition);
        reportRepairStatistics.setCompleteCount(completeReportRepairs.size());
        //满意度
        double avgSatisfactionScore = incidentSatisfactionTableRepository.getAvgSatisfactionScore(stationIdList);
        BigDecimal bd = new BigDecimal(avgSatisfactionScore);
        avgSatisfactionScore = bd.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
        reportRepairStatistics.setSatisfaction(avgSatisfactionScore);

        return  reportRepairStatistics;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void distributeReportRepair(Long id, Long distributeOrgId, Long distributePersonId) throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(id);
        String currentStatus = reportRepair.getCurrentStatus();
        if (!EstateManageConstant.Current_Status_Type.To_Be_Distributed.value().equals(currentStatus)){
            throw new ArgumentErrorException("该事项正在处理中或已结束，无法进行分派操作！");
        }
        if (reportRepair.getStationId() != null){
            ResponseEntity<ResultObject<RealStation>> realStationResponseEntity = authorityClient.searchRealStationById(reportRepair.getStationId());
            if (realStationResponseEntity.getStatusCode().is2xxSuccessful()){
                Object results = realStationResponseEntity.getBody().getResults();
                RealStation realStation = JSON.toJavaObject((JSON) JSON.toJSON(results), RealStation.class);
                reportRepair.setStationName(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
            }
        }

        if (reportRepair.getCompanyId() != null){
            ResponseEntity<ResultObject<Company>> companyResponseEntity = authorityClient.getCompanyById(reportRepair.getCompanyId());
            if (companyResponseEntity.getStatusCode().is2xxSuccessful()){
                Object results = companyResponseEntity.getBody().getResults();
                Company company = JSON.toJavaObject((JSON) JSON.toJSON(results), Company.class);
                reportRepair.setCompanyName(company.getTitle());
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        reportRepair.setOrgId(distributeOrgId);
        reportRepair.setCurrentOperatorId(distributePersonId);
        reportRepair.setLastOperatorId(myHeaderUtil.getHeaderUser());
        reportRepair.setUpdateTime(sdf.format(new Date()));
        reportRepair.setCurrentStatus(EstateManageConstant.Current_Status_Type.Processing.value());
        reportRepairRepository.updateByPrimaryKey(reportRepair);

        ProcessStatus distributeProcess = new ProcessStatus();
        distributeProcess.setReportForRepairId(id);
        distributeProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Allocate_Demand.value());
        distributeProcess.setCurrentStatus(EstateManageConstant.Current_Status_Type.Processing.value());
        distributeProcess.setOperatorId(myHeaderUtil.getHeaderUser());
        distributeProcess.setOrgId(distributeOrgId);
        distributeProcess.setHandlerId(distributePersonId);
        distributeProcess.setCreateTime(sdf.format(new Date()));
        distributeProcess.setUpdateTime(sdf.format(new Date()));
        processStatusRepository.create(distributeProcess);
        try {
            sendMessageCenter(reportRepair,headerUser,"app",distributeOrgId,distributePersonId);
            if (ServerContextHolder.getContext().getProjectCode() != null) {
                pushMessageToApp(String.valueOf(distributePersonId), ServerContextHolder.getContext().getProjectCode(), reportRepair);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /*//创建新的线程发送到消息中心
        new Thread(()-> {
            try {
                sendMessageCenter(reportRepair,headerUser,"app",distributeOrgId,distributePersonId);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();*/
    }

    @Override
    public void urgeReportRepair(Long id) {
        ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(id);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        reportRepair.setUpdateTime(sdf.format(new Date()));
        reportRepair.setIsUrge(EstateManageConstant.Urge_Type.Urge.value());
        reportRepairRepository.updateByPrimaryKey(reportRepair);
    }

    @Override
    public ReportRepair viewReportRepair(Long id) {
        ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(id);
        return reportRepair;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleReportRepair(ReportRepairHandle reportRepairHandle) throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("用户信息已过期，请重新登录！");
        }
        ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(reportRepairHandle.getReportRepairId());
        //如果状态为已完成或中止，则不能进行处理操作
        if (EstateManageConstant.Current_Status_Type.Completed.value().equals(reportRepair.getCurrentStatus())){
            throw new ArgumentErrorException("当前事项已完成，无法进行更新操作！");
        }
        if (EstateManageConstant.Current_Status_Type.Suspension.value().equals(reportRepair.getCurrentStatus())){
            throw new ArgumentErrorException("当前事项已中止，无法进行更新操作！");
        }
        if (EstateManageConstant.Current_Status_Type.To_Be_Distributed.value().equals(reportRepair.getCurrentStatus())){
            throw new ArgumentErrorException("当前事项未分发，无法进行更新操作！");
        }
        if (EstateManageConstant.Current_Status_Type.Revoke.value().equals(reportRepairHandle.getTargetStatus())){
            throw new ArgumentErrorException("当前事项已撤销，无法进行更新操作！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        reportRepair.setProcessingTime(sdf.format(new Date()));
        //如果是退回操作，跟进部门和当前处理人置空,处理时间置空
        if (EstateManageConstant.Current_Status_Type.To_Be_Distributed.value().equals(reportRepairHandle.getTargetStatus())){
            reportRepair.setCurrentOperatorId(null);
            reportRepair.setOrgId(null);
            reportRepair.setCurrentStatus(EstateManageConstant.Current_Status_Type.To_Be_Distributed.value());
            reportRepair.setProcessingTime(null);
        }else {
            reportRepair.setCurrentOperatorId(headerUser);
        }
        reportRepair.setUpdateTime(sdf.format(new Date()));
        reportRepair.setCurrentStatus(reportRepairHandle.getTargetStatus());
        reportRepair.setLastOperatorId(headerUser);
        reportRepair.setProcessingFeedback(reportRepairHandle.getProcessing_feedback());
        reportRepair.setProcessPictures(reportRepairHandle.getProcess_pictures());
        //归属园区名称翻译
        if (reportRepair.getStationId() != null){
            ResponseEntity<ResultObject<RealStation>> realStationResponseEntity = authorityClient.searchRealStationById(reportRepair.getStationId());
            if (realStationResponseEntity.getStatusCode().is2xxSuccessful()){
                Object results = realStationResponseEntity.getBody().getResults();
                RealStation realStation = JSON.toJavaObject((JSON) JSON.toJSON(results), RealStation.class);
                reportRepair.setStationName(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
            }
        }
        //企业名称翻译
        if (reportRepair.getCompanyId() != null){
            ResponseEntity<ResultObject<Company>> companyResponseEntity = authorityClient.getCompanyById(reportRepair.getCompanyId());
            if (companyResponseEntity.getStatusCode().is2xxSuccessful()){
                Object results = companyResponseEntity.getBody().getResults();
                Company company = JSON.toJavaObject((JSON) JSON.toJSON(results), Company.class);
                reportRepair.setCompanyName(company.getTitle());
            }
        }
        reportRepairRepository.backUpdateReportRepair(reportRepair);

        String targetStatus = reportRepairHandle.getTargetStatus();
        ProcessStatus handleProcess = new ProcessStatus();
        handleProcess.setReportForRepairId(reportRepairHandle.getReportRepairId());
        handleProcess.setProcessingTime(sdf.format(new Date()));
        handleProcess.setCurrentStatus(reportRepairHandle.getTargetStatus());
        handleProcess.setOperatorId(headerUser);
        //如果是退回操作，处理人置空
        if (EstateManageConstant.Current_Status_Type.To_Be_Distributed.value().equals(reportRepairHandle.getTargetStatus())){
            handleProcess.setHandlerId(null);
            handleProcess.setOrgId(null);
        }else {
            handleProcess.setHandlerId(headerUser);
            handleProcess.setOrgId(reportRepair.getOrgId());
        }
        handleProcess.setProcessPictures(reportRepairHandle.getProcess_pictures());
        handleProcess.setProcessingFeedback(reportRepairHandle.getProcessing_feedback());
        handleProcess.setCreateTime(sdf.format(new Date()));
        handleProcess.setUpdateTime(sdf.format(new Date()));
        if (EstateManageConstant.Current_Status_Type.Processing.value().equals(targetStatus)){
            handleProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Handle_Demand.value());
        }else if (EstateManageConstant.Current_Status_Type.Completed.value().equals(targetStatus)){
            handleProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Completed.value());
        }else if (EstateManageConstant.Current_Status_Type.Suspension.value().equals(targetStatus)){
            handleProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Suspension.value());
        }else if (EstateManageConstant.Current_Status_Type.To_Be_Distributed.value().equals(targetStatus)){
            handleProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Send_Back.value());
        }
        processStatusRepository.create(handleProcess);

        //当报事报修完成或中止时，发送到消息中心
        if (EstateManageConstant.Current_Status_Type.Completed.value().equals(reportRepairHandle.getTargetStatus()) ||
            EstateManageConstant.Current_Status_Type.Suspension.value().equals(reportRepairHandle.getTargetStatus())){
            try {
                sendMessageCenter(reportRepair, headerUser, "weChat", null, reportRepair.getContactPersonId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /*//创建新的线程发送到消息中心
            new Thread(()-> {
                try {
                    sendMessageCenter(reportRepair, headerUser, "weChat", null, reportRepair.getContactPersonId());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();*/
        }
    }

    @Override
    public List<ProcessStatus> getFeedbackHistory(Long id) {
        return processStatusRepository.getFeedbackHistory(id);
    }

    @Override
    public List<ProcessStatus> getNodeHistory(Long id) {
        List<ProcessStatus> nodeHistory = processStatusRepository.getProcessByReportRepairId(id);
        for (ProcessStatus processStatus : nodeHistory) {
            if (EstateManageConstant.Process_Node_Type.Submit_Demand.value().equals(processStatus.getProcessNode())){
                ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(id);
                processStatus.setProcessPictures(reportRepair.getProblemPictures());
                processStatus.setProcessingFeedback(reportRepair.getProblemDescription());
            }
            List<IncidentSatisfactionTable> incidentSatisfactionTables = incidentSatisfactionTableRepository.searchIncidentSatisfactionTableByReportForRepairId(id);
            if (!CollectionUtil.isEmpty(incidentSatisfactionTables)) {
                if (EstateManageConstant.Current_Status_Type.Completed.value().equals(processStatus.getCurrentStatus())) {
                    processStatus.setSatisfactionScore(incidentSatisfactionTables.get(0).getSatisfactionScore());
                    processStatus.setSatisfactionFeedback(incidentSatisfactionTables.get(0).getFeedback());
                }
            }
        }
        return nodeHistory;
    }

    @Override
    public void revokeReportRepair(Long id) throws ArgumentErrorException {
        ReportRepair reportRepair = reportRepairRepository.searchByPrimaryKey(id);
        if (EstateManageConstant.Current_Status_Type.Completed.value().equals(reportRepair.getCurrentStatus())){
            throw new ArgumentErrorException("当前事项已完成，无法进行撤销操作！");
        }
        if (EstateManageConstant.Current_Status_Type.Suspension.value().equals(reportRepair.getCurrentStatus())){
            throw new ArgumentErrorException("当前事项已中止，无法进行撤销操作！");
        }
        if (EstateManageConstant.Current_Status_Type.Revoke.value().equals(reportRepair.getCurrentStatus())){
            throw new ArgumentErrorException("当前事项已撤销，无法进行撤销操作！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        reportRepair.setCurrentStatus(EstateManageConstant.Current_Status_Type.Revoke.value());
        reportRepair.setLastOperatorId(myHeaderUtil.getHeaderUser());
        reportRepair.setUpdateTime(sdf.format(new Date()));
        reportRepairRepository.updateByPrimaryKey(reportRepair);

        ProcessStatus revokeProcess = new ProcessStatus();
        revokeProcess.setReportForRepairId(reportRepair.getId());
        revokeProcess.setCreateTime(sdf.format(new Date()));
        revokeProcess.setUpdateTime(sdf.format(new Date()));
        revokeProcess.setCurrentStatus(EstateManageConstant.Current_Status_Type.Revoke.value());
        revokeProcess.setProcessNode(EstateManageConstant.Process_Node_Type.Revoke.value());
        revokeProcess.setOperatorId(myHeaderUtil.getHeaderUser());
        processStatusRepository.create(revokeProcess);
    }

    @Override
    public List<ProcessStatus> getProcessList(Long id) {
        List<ProcessStatus> nodeHistory = processStatusRepository.getProcessByReportRepairId(id);
        for (ProcessStatus processStatus : nodeHistory) {
            List<IncidentSatisfactionTable> incidentSatisfactionTables = incidentSatisfactionTableRepository.searchIncidentSatisfactionTableByReportForRepairId(id);
            if (!CollectionUtil.isEmpty(incidentSatisfactionTables)) {
                if (EstateManageConstant.Current_Status_Type.Completed.value().equals(processStatus.getCurrentStatus())) {
                    processStatus.setSatisfactionScore(incidentSatisfactionTables.get(0).getSatisfactionScore());
                    processStatus.setSatisfactionFeedback(incidentSatisfactionTables.get(0).getFeedback());
                }
            }
        }
        return nodeHistory;
    }

    @Override
    public ReportRepairView test(Long id) {
        ReportRepairView reportRepairView = new ReportRepairView();
        ReportRepair reportRepair = viewReportRepair(id);
        List<ProcessStatus> processList = getProcessList(id);
        reportRepairView.setReportRepair(reportRepair);
        reportRepairView.setReportRepairProcess(processList);
        return reportRepairView;
    }
}
